﻿using System;
using System.Net;
using System.Windows;
using System.IO;
using System.Xml;
using IkeCode.WP7.HQReader.Base;
using System.Xml.Linq;
using System.Linq;
using System.Collections.Generic;
using System.ServiceModel.Syndication;
using IkeCode.WP7.HQReader.Interfaces;
using IkeCode.WP7.HQReader.Model;
using GalaSoft.MvvmLight.Ioc;
using System.Text.RegularExpressions;
using System.Collections;
using IkeCode.WP7.Toolkit.Persist;
using IkeCode.WP7.Toolkit;
using IkeCode.WP7.Toolkit.Core.Linq;
using IkeCode.WP7.Toolkit.HttpRequest;

namespace IkeCode.WP7.HQReader.Services
{
    /// <summary>
    /// Contains all methods for feed manipulation (get/post)
    /// </summary>
    public class FeedDataService : BaseDataService, IFeedDataService
    {
        IcLoadingService _loadingService;

        /// <summary>
        /// Default constructor
        /// </summary>
        public FeedDataService()
        {
            _loadingService = SimpleIoc.Default.GetInstance<IcLoadingService>();
        }

        /// <summary>
        /// Get All Feeds that exists in Cache (IsolatedStorage)
        /// </summary>
        /// <param name="trySync">Try to online sync all publishers</param>
        /// <param name="callback">Callback with List of IkeCode.WP7.HQReader.Interfaces.IIcFeed result or Exception, in error cases</param>
        public void GetAllFeeds(bool trySync, Action<Dictionary<IIcFeedPublisher, List<IIcFeed>>, Exception> callback)
        {
            try
            {
                _loadingService.LoadingSwitch(true);
                var result = new Dictionary<IIcFeedPublisher, List<IIcFeed>>();
                var smartPersistService = SimpleIoc.Default.GetInstance<IcSmartPersistService>();
                SimpleIoc.Default.GetInstance<IFeedPublisherDataService>().GetPublishers((publishers, ex) =>
                {
                    if (ex != null) { throw ex; }
                    else
                    {
                        foreach (var publisher in publishers)
                        {
                            try
                            {
                                this.GetFeeds(trySync, publisher, (feedList, error) =>
                                {
                                    result.Add(publisher, feedList);
                                });
                            }
                            catch (FileEmptyException) { }
                        }

                        _loadingService.LoadingSwitch(false);

                        callback(result, null);
                    }
                });
            }
            catch (Exception e)
            {
                _loadingService.ErrorSwitch();
                callback(null, e);
            }
        }

        /// <summary>
        /// Get All feeds for specific publisher in cache and try to get online updates to store.
        /// </summary>
        /// <param name="trySync">Try to online sync feed items</param>
        /// <param name="publisher">IIcFeedPublisher object</param>
        /// <param name="callback">Action to be executed</param>
        public void GetFeeds(bool trySync, IIcFeedPublisher publisher, Action<List<IIcFeed>, Exception> callback)
        {
            try
            {
                _loadingService.LoadingSwitch(true);
                var smartPersistService = SimpleIoc.Default.GetInstance<IcSmartPersistService>();
                var isfFeedList = new List<IIcFeed>();

                try
                {
                    isfFeedList = smartPersistService.LoadObjectList<IcFeedModel, IIcFeed>(publisher.Url.Host);
                }
                catch (Exception) { }

                if (trySync)
                {
                    AsyncCall.Get.Syndication(publisher.Url, (result, ex) =>
                    {
                        if (ex != null) { throw ex; }
                        else
                        {
                            var item = new IcFeedModel(result);
                            var items = item.GetList().Except(isfFeedList, new IcComparer<IIcFeed>((first, second) => first.UniqueId == second.UniqueId)).ToList();
                            isfFeedList.AddRange(items);
                        }
                        smartPersistService.AddObjectList<IcFeedModel, IIcFeed>(isfFeedList, false, publisher.Url.Host);

                        _loadingService.LoadingSwitch(false);
                        callback(isfFeedList, null);
                    });
                }
                else
                {
                    _loadingService.LoadingSwitch(false);
                    callback(isfFeedList, null);
                }
            }
            catch (Exception e)
            {
                _loadingService.ErrorSwitch();
                callback(null, e);
            }
        }
    }
}